#include "logger.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <time.h>

#ifdef _WIN32
#include <io.h>
#include <windows.h>
#define ISATTY _isatty
#define FILENO _fileno
#else
#include <unistd.h>
#define ISATTY isatty
#define FILENO fileno
#endif

// 全局日志等级
static LogLevel g_log_level = LOG_LEVEL_DEBUG;

// 颜色输出状态 (0: 禁用, 1: 启用, -1: 未初始化)
static int g_color_enabled = -1;

// 初始化日志系统（自动检测颜色支持）
void log_init(void) {
    // 如果已经初始化过则跳过
    if (g_color_enabled != -1) return;
    
    // 默认启用颜色（如果支持）
    g_color_enabled = 0;
    
    // 检查标准错误是否是终端
    if (ISATTY(FILENO(stderr))) {
        // 检查是否在Windows终端（支持ANSI颜色）
        #ifdef _WIN32
        // Windows 10+ 支持ANSI颜色
        HANDLE hConsole = GetStdHandle(STD_ERROR_HANDLE);
        DWORD mode;
        if (GetConsoleMode(hConsole, &mode)) {
            if (SetConsoleMode(hConsole, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING)) {
                g_color_enabled = 1;
                // 恢复原模式
                SetConsoleMode(hConsole, mode);
            }
        }
        #else
        // Unix-like系统默认支持
        g_color_enabled = 1;
        #endif
    }
}

// 设置全局日志等级
void _set_log_level(LogLevel level) {
    g_log_level = level;
}

// 获取当前日志等级
LogLevel get_log_level(void) {
    return g_log_level;
}

// 启用/禁用颜色输出
void log_enable_color(int enable) {
    // 确保已初始化
    if (g_color_enabled == -1) log_init();
    g_color_enabled = enable ? 1 : 0;
}

// 日志输出实现
void log_output(LogLevel level, const char* file, int line, 
                const char* func, const char* format, ...) 
{
    // 确保颜色状态已初始化
    if (g_color_enabled == -1) log_init();
    
    // 获取当前时间
    time_t t = time(NULL);
    struct tm *tm_info = localtime(&t);
    char time_str[20];
    strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", tm_info);
    
    // 日志等级字符串和颜色代码
    const char *level_str = "";
    const char *color_code = "";
    const char *color_reset = "";
    
    // 设置颜色（如果启用）
    if (g_color_enabled) {
        color_reset = "\033[0m";
        switch(level) {
            case LOG_LEVEL_DEBUG: 
                level_str = "DEBUG";
                color_code = "\033[36m"; // 青色
                break;
            case LOG_LEVEL_INFO:  
                level_str = "INFO ";
                color_code = "\033[32m"; // 绿色
                break;
            case LOG_LEVEL_WARN:  
                level_str = "WARN ";
                color_code = "\033[33m"; // 黄色
                break;
            case LOG_LEVEL_ERROR: 
                level_str = "ERROR";
                color_code = "\033[31m"; // 红色
                break;
            case LOG_LEVEL_FATAL: 
                level_str = "FATAL";
                color_code = "\033[35m"; // 紫色
                break;
            default:              
                level_str = "UNKWN";
                color_code = "\033[0m";
                break;
        }
    } else {
        switch(level) {
            case LOG_LEVEL_DEBUG: level_str = "DEBUG"; break;
            case LOG_LEVEL_INFO:  level_str = "INFO "; break;
            case LOG_LEVEL_WARN:  level_str = "WARN "; break;
            case LOG_LEVEL_ERROR: level_str = "ERROR"; break;
            case LOG_LEVEL_FATAL: level_str = "FATAL"; break;
            default:              level_str = "UNKWN"; break;
        }
    }
    
    // 提取文件名（不含路径）
    const char *file_name = strrchr(file, '/');
    if (!file_name) file_name = strrchr(file, '\\');
    file_name = file_name ? file_name + 1 : file;
    
    // 打印日志头信息
    if (g_color_enabled) {
        fprintf(stderr, "%s[%s] [%s] [%s:%d] [%s]%s ", 
                color_code, time_str, level_str, file_name, line, func, color_reset);
    } else {
        fprintf(stderr, "[%s] [%s] [%s:%d] [%s] ", 
                time_str, level_str, file_name, line, func);
    }
    
    // 打印用户日志内容
    va_list args;
    va_start(args, format);
    vfprintf(stderr, format, args);
    va_end(args);
    
    // 添加换行符
    fputc('\n', stderr);
    fflush(stderr);  // 确保及时输出
}